package pl.wr.physics.units.quantum.number;

import pl.wr.physics.exceptions.QuantumException;
import pl.wr.physics.units.AbstractUnit;
import pl.wr.physics.units.SI.Prefix;
import pl.wr.physics.units.quantum.QuantumUnit;

public class PrincipalQuantumNumber implements QuantumUnit {

    /**
     * Principal quantum number.
     */
    private int n;

    /**
     * Make principal quantum number from range: 1 to 7. Oversize throw
     * QuantumException.
     * 
     * @param n
     *            - int value of magnetic quantum number
     */
    public PrincipalQuantumNumber(int n) {
        this.n = n;
    }

    /**
     * @return int value of principal quantum number.
     */
    public int getN() {
        return n;
    }

    /**
     * Set the principal quantum number from range: 1-7. Oversize throw
     * QuantumException.
     * 
     * @param n
     *            - int value of principal quantum number.
     */
    public void setN(int n) {
        if (n > 0 && n < 8) {
            this.n = n;
        } else {
            throw new QuantumException();
        }
    }

    private static class PrincipalQuantumNumberCache {
        static final PrincipalQuantumNumber cache[] = new PrincipalQuantumNumber[6];

        static {
            int j = 1;
            for (int k = 0; k < cache.length; k++)
                cache[k] = new PrincipalQuantumNumber(j++);
        }

        private PrincipalQuantumNumberCache() {
        }
    }

    /**
     * Returns an PrincipalQuantumNumber instance representing the specified int
     * value. This method will always cache values in the range 1 to 7.
     * 
     * @param l
     * @return
     */
    public static PrincipalQuantumNumber valueOf(int n) {
        checkScope(n);
        return PrincipalQuantumNumberCache.cache[n - 1];
    }

    private static void checkScope(int n) {
        if (n >= 1 && n <= 7) {
            // is OK
        } else {
            throw new QuantumException("Bad scope of number: " + n);
        }
    }

    @Override
    public AbstractUnit getSIValue() {
        return new AbstractUnit(Prefix.basic, n, null) {
        };
    }

}
